/*
 * @Author: shenghao.xu
 * @Date: 2023-06-05 10:51:33
 * @LastEditors: shenghao.xu
 * @LastEditTime: 2023-07-06 12:56:10
 * @Description:    app层接口
 * email:545403892@qq.com
 * Copyright (c) 2023 by shenghao.xu, All Rights Reserved.
 */

#include "app.h"
#include "hart.h"
#include "hart_frame.h"
#include "flow.h"
#ifdef STM32
#include "tim.h"
#include "board.h"
#endif

app_dynamics_t app_dynamics;
static struct flow fl_systom_inspection;
/**
 * @description: 发送数据(hart协议数据帧)
 * @param {uint8_t} *txBuf
 * @param {uint16_t} len
 * @return {*}
 */
static void response(uint8_t *data, uint16_t len)
{
#ifdef STM32
    uart1_send_data(data, len);
#else
    LOG_HEX(data, len);
#endif
}

/**
 * @description: flash读取接口
 * @param {uint32_t} addr
 * @param {uint8_t} *data
 * @param {uint16_t} len
 * @return {*}
 */
static BOOL flash_read(uint32_t addr, uint8_t *data, uint16_t len)
{
    eeprom_read(addr, data, len);
    return TRUE;
}

/**
 * @description: flash写入接口
 * @param {uint32_t} addr
 * @param {uint8_t} *data
 * @param {uint16_t} len
 * @return {*}
 */
static BOOL flash_write(uint32_t addr, uint8_t *data, uint16_t len)
{
    eeprom_write(addr, data, len);
    return TRUE;
}

/**
 * @description: 执行自检
 * @param {*}
 * @return {*}
 */
static void perform_self_test(void)
{
}

/**
 * @description: 设备复位
 * @param {*}
 * @return {*}
 */
static void device_reset(void)
{
}

/**
 * @description: 设备呼叫,0一直呼叫，1-255秒
 * @param {*}
 * @return {*}
 */
static void squawk_control(BOOL open, uint8_t second)
{
}

/**
 * @description: 技术人员按下一个特殊的按钮或按钮组合，指示从机应响应command74
 * @param {*}
 * @return {*}
 */
static BOOL armed(void)
{
    return TRUE;
}

/**
 * @description: 设置动态变量
 * @return {*}
 */
static BOOL set_dynamics(device_variable_dynamics_t *const dynamics)
{
    app_analog_quantity_t *analog_quantity = &app_dynamics.analog_quantity;
    app_digital_quantity_t *digital_quantity = &app_dynamics.digital_quantity;
    dynamics->dynamics_user.analog_quantity.input_current = &analog_quantity->input_current;
    dynamics->dynamics_user.analog_quantity.valve_feedback = &analog_quantity->valve_feedback;
    dynamics->dynamics_user.analog_quantity.atmospheric_pressure_source = &analog_quantity->atmospheric_pressure_source;
    dynamics->dynamics_user.analog_quantity.pressure_at_port_a = &analog_quantity->pressure_at_port_a;
    dynamics->dynamics_user.analog_quantity.pressure_at_port_b = &analog_quantity->pressure_at_port_b;
    dynamics->dynamics_user.analog_quantity.amplifier_circuit = &analog_quantity->amplifier_circuit;
    dynamics->dynamics_user.analog_quantity.built_in_temperature = &analog_quantity->built_in_temperature;
    dynamics->dynamics_user.analog_quantity.ip_output_detection = &analog_quantity->ip_output_detection;
    dynamics->dynamics_user.analog_quantity.valve_percentage = &analog_quantity->valve_percentage;

    dynamics->dynamics_user.digital_quantity.input_current = &digital_quantity->input_current;
    dynamics->dynamics_user.digital_quantity.valve_feedback = &digital_quantity->valve_feedback;
    dynamics->dynamics_user.digital_quantity.atmospheric_pressure_source = &digital_quantity->atmospheric_pressure_source;
    dynamics->dynamics_user.digital_quantity.pressure_at_port_a = &digital_quantity->pressure_at_port_a;
    dynamics->dynamics_user.digital_quantity.pressure_at_port_b = &digital_quantity->pressure_at_port_b;
    dynamics->dynamics_user.digital_quantity.amplifier_circuit = &digital_quantity->amplifier_circuit;
    dynamics->dynamics_user.digital_quantity.built_in_temperature = &digital_quantity->built_in_temperature;
    dynamics->dynamics_user.digital_quantity.ip_output_detection = &digital_quantity->ip_output_detection;
    dynamics->dynamics_user.digital_quantity.target_row = &digital_quantity->target_row;
    dynamics->dynamics_user.digital_quantity.current_row = &digital_quantity->current_row;
    dynamics->dynamics_user.digital_quantity.friction = &digital_quantity->friction;
    dynamics->dynamics_user.digital_quantity.spring_force = &digital_quantity->spring_force;

    return TRUE;
}

static BOOL user_common_event(hart_interface_user_event_e event, const void *const data)
{
    switch (event)
    {
    case HART_COMMAND_257_EVENT:
        // 寻找、计算P / I / D
        break;
    case HART_COMMAND_258_EVENT:
        // 计算 摩擦力
        break;
    case HART_COMMAND_259_EVENT:
        // 计算 弹簧力
        break;
    default:
        return FALSE;
    }
    return TRUE;
}

/**
 * @description: hart模块初始化
 * @return {*}
 */
static BOOL app_hart_init(void)
{
    hart_init_t init;
    init.hart_protocol_version = HART_PROTOCOL_VERSION_7;
    init.dir = MODULE_SLAVE;
    init.interface.response = response;
    init.interface.flash_read = flash_read;
    init.interface.flash_write = flash_write;
    init.interface.perform_self_test = perform_self_test;
    init.interface.device_reset = device_reset;
    init.interface.squawk_control = squawk_control;
    init.interface.armed = armed;
    init.interface.set_dynamics = set_dynamics;
    init.interface.user_common_event = user_common_event;
    return hart_init(&init);
}

/**
 * @description: 系统检测
 * @param {struct flow *} fl
 * @return {*}
 */
static uint8_t systom_inspection(struct flow *fl)
{
    app_analog_quantity_t *analog_quantity = &app_dynamics.analog_quantity;
    app_digital_quantity_t *digital_quantity = &app_dynamics.digital_quantity;
    FL_HEAD(fl);
    for (;;)
    {
        FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC); /* 延时1000毫秒 */
        analog_quantity->input_current += 0.1;
        analog_quantity->valve_feedback += 1;
        analog_quantity->atmospheric_pressure_source += 1;
        analog_quantity->pressure_at_port_a += 1;
        analog_quantity->pressure_at_port_b += 1;
        analog_quantity->amplifier_circuit += 1;
        analog_quantity->built_in_temperature += 0.1;
        analog_quantity->ip_output_detection += 1;
        analog_quantity->valve_percentage += 0.1;

        digital_quantity->input_current += 0.1;
        digital_quantity->valve_feedback += 1;
        digital_quantity->atmospheric_pressure_source += 1;
        digital_quantity->pressure_at_port_a += 1;
        digital_quantity->pressure_at_port_b += 1;
        digital_quantity->amplifier_circuit += 1;
        digital_quantity->built_in_temperature += 0.1;
        digital_quantity->ip_output_detection += 1;
        digital_quantity->target_row += 1;
        digital_quantity->current_row += 1;
        digital_quantity->friction += 1;
        digital_quantity->spring_force += 1;
    }
    FL_TAIL(fl);
}

/**
 * @description: 流程启动
 * @return {*}
 */
static void flow_start(void)
{
    systom_inspection(&fl_systom_inspection); // 系统检测
}
/**
 * @description: 初始化流程
 * @return {*}
 */
static void flow_init(void)
{
    FL_INIT(&fl_systom_inspection); // 系统检测

    HAL_TIM_Base_Start_IT(&htim6); // 任务进程的定时器使能
}

void app_init(void)
{
    if (FALSE == app_hart_init())
    {
        // TODO 初始化失败
        DBG_ASSERT(FALSE __DBG_LINE);
    }
    flow_init();
}

void app_start()
{
    flow_start();
}
